<?php


/**
 * 责任链模式
 * 
 * 概述：使多个对象都有机会处理请求，从而避免了请求的发送者和接收者之间的耦合关系。
 * 将这些对象连成一条链，并沿着这条链传递该请求，直到有对象处理它为止。
 * 
 * 类型：行为类模式
 * 
 * 作用：请求的链式处理。
 * 
 * 角色：
 * 
 * 优点：
 * 
 * 缺点：
 * 
 */

abstract class Approver
{
	protected $successor;
	public $name;
	
	public function __construct($name)
	{
		$this->name = $name;
	}
		
	public function setSuccessor(Approver $successor)
	{
		$this->successor = $successor;
	}
	
	public abstract function processRequest(LeaveRequest $request);
}

class Director extends Approver
{
	public function processRequest(LeaveRequest $request)
	{
		if ($request->getDay() < 3) {
			echo "主任：{$this->name}  批准请假条：{$request->getName()}  {$request->getDay()}天<br/>";
		} else 
			$this->successor->processRequest($request);
	}
}

class Manager extends Approver
{
	public function processRequest(LeaveRequest $request)
	{
		if ($request->getDay() < 10) {
			echo "经理：{$this->name}  批准请假条：{$request->getName()}  {$request->getDay()}天<br/>";
		} else 
			$this->successor->processRequest($request);
	}
}

class GeneralManager extends Approver
{
	public function processRequest(LeaveRequest $request)
	{
		if ($request->getDay() < 30) {
			echo "总经理：{$this->name}  批准请假条：{$request->getName()}  {$request->getDay()}天<br/>";
		} else 
			echo "{$request->getName()}  {$request->getDay()}天的请假条，不能被批准。<br/>";
	}
}

class LeaveRequest
{
	private $_name;
	private $_day;
	
	public function __construct($name, $day)
	{
		$this->_name = $name;
		$this->_day = $day;
	}
	
	public function getName()
	{
		return $this->_name;
	}
	
	public function getDay()
	{
		return $this->_day;
	}
}

class Client
{
	public static function main()
	{
		$zhangsan = new Director('张三');
		$lisi = new Manager('李四');
		$wangwu = new GeneralManager('王五');
		
		//创建责任链
		$zhangsan->setSuccessor($lisi);
		$lisi->setSuccessor($wangwu);
		
		echo '请假条批准规则：主任小于3天，经理3-10天，总经理10-30天，其它不批准。<br/>';
		
		//创建请假条
		$leaveRequest = new LeaveRequest('赵六', 2);
		$zhangsan->processRequest($leaveRequest);
		
		$leaveRequest = new LeaveRequest('陈七', 5);
		$zhangsan->processRequest($leaveRequest);
		
		$leaveRequest = new LeaveRequest('鄢八', 20);
		$zhangsan->processRequest($leaveRequest);
		
		$leaveRequest = new LeaveRequest('粟刚', 40);
		$zhangsan->processRequest($leaveRequest);
	}
}

Client::main();